// -*-mode:c++; coding:utf-8-*-

#ifndef _TABLET_SERVER_CONFIGURATION_HPP_
#define _TABLET_SERVER_CONFIGURATION_HPP_

#include <string>

#include <boost/filesystem/path.hpp>

#include <appframe/config.hpp>

//
// 子表服务器需要的配置信息，与配置文件中的字段对应。
// 

struct TabletServerConfiguration {

public:
	// typedefs
	typedef int size_type;

public:
	TabletServerConfiguration ();

	~TabletServerConfiguration () {}

	const std::string &home () const {
		return _home;
	}

public:
	
	// 默认值
	enum {
		LOG_QUEUE_SIZE = 1024,

		CLIENT_HANDLER_NUMBER = 5,
		MASTER_HANDLER_NUMBER = 5,
		EPOLL_NUMBER = 1,

		MASTER_PORT = 20081,

		HEART_BEAT_INTERVAL = 15, // 15s

		RETRY_TIMES = 3,
		RETRY_INTERVAL = 3, // 3ms

		// 较长时间的等待
		WAIT_INTERVAL = 15 * 1000, // 15s

		// 等待元子表地址更新的间隔
		WAIT_FOR_META_ADDRESS_INTERVAL = 15 * 1000, // 15s

		WAIT_SECONDS_FOR_MASTER_REPLY = 5, // 5s，等待主服务器响应的时间
		WAIT_SECONDS_FOR_TABLET_IDLE = 3, // 3s，等待子表空闲的时间

		ROLL_BACK_INTERVAL = 600, // 10 minutes

		MAX_LOG_BYTES = 1024 * 1024 * 10, // 默认一个日志文件最大10M
		CACHE_LOGFILE_SIZE = 1024 * 1024 * 10, // 10M

		CLIENT_LISTEN_PORT = 20083,

		// options default value and lower bound value
		MINOR_COMPACT_INTERVAL = 600,	   // seconds,  10 min
		MINOR_COMPACT_CHECK_INTERVAL = 60, // seconds,  1 min
		MAJOR_COMPACT_INTERVAL = 24 * 60 * 60, // seconds, 主要紧缩间隔，默认为一天，这是为了将过期或无用的数据丢掉。
		MAJOR_COMPACT_CHECK_INTERVAL = 600, // seconds, 10 min
		SCANNER_CHECK_INTERVAL = 60,	    // seconds, 1 min
		SCANNER_LIFETIME = 600,		    // seconds, 10 min
		LOWER_BOUND_OF_MAX_NUM_SSTABLE = 3,

		TABLET_CHECK_INTERVAL = 10 * 60, // seconds, 10 min

		BLOCK_CACHE_LIFETIME = 60 * 60 * 3, // seconds, 3 hours for debug
		BLOCK_CACHE_CHECK_INTERVAL = 60 * 60, // seconds, 1 hours

		MAX_CACHE_MEMORY = 64 * 1024 * 1024, // 64M

		END
	};

	// 加载后的值

	std::string xbase_root_path;

	// 日志队列大小
	size_type log_queue_size;

	size_type heart_beat_interval;

	size_type client_listen_port; // 如果可以，在监听后再设置
				      // 该端口而不是从文件中加载

	std::string master_ip;
	size_type master_port;

	std::string tabletserver_ip; // 本地主机IP，最好通过程序获取

	size_type client_handler_number;
	size_type master_handler_number;
	size_type epoll_number;

	size_type retry_times;
	size_type retry_interval;

	size_type wait_interval;
	size_type wait_for_meta_address_interval;
	size_type wait_seconds_for_master_reply;
	size_type wait_seconds_for_tablet_idle;

	size_type roll_back_interval;

	size_type max_log_bytes;
	size_type cache_logfile_size;
	std::string cache_logfile_dir;

	size_type minor_compact_interval;
	size_type minor_compact_check_interval;
	size_type major_compact_interval;
	size_type major_compact_check_interval;
	size_type scanner_check_interval;
	size_type scanner_lifetime;
	size_type lower_bound_of_max_num_sstable;

	size_type tablet_check_interval;

	size_type block_cache_lifetime;
	size_type block_cache_check_interval;

	size_type max_cache_memory;

	void load();

protected:
	std::string serverConfFileName () const {
		return (boost::filesystem::path(_home) / CONF_FILE_NAME).string();
	}
	std::string logConfFileName () const {
		return (boost::filesystem::path(_home) / LOG_FILE_NAME).string();
	}
	std::string gfs_conf_filename() const {
		return (boost::filesystem::path(_home) / GFS_CONF_FILE_NAME).string();
	}
	
private:
	std::string _home;
	Config _config;

public:
	static bool LOGGER_CONFIGURED;
	//DECL_LOGGER (TABLET_SERVER_LOGGER);
	static const char ENV_HOME_PATH [];
	static const char CONF_FILE_NAME[];
	static const char GFS_CONF_FILE_NAME[];
	static const char LOG_FILE_NAME [];
};

#endif	// _TABLET_SERVER_CONFIGURATION_HPP_
